package com.baikeyang.bike.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.log4j.Logger;

import com.baikeyang.bike.bean.BikeBean;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Pipeline;

/**
 * Redis工具类
 * @author BaiKeyang
 *
 */
public final class RedisUtil {
	private static final Logger logger = Logger.getLogger(RedisUtil.class);
	//Redis服务器IP
	private static String ADDR = PropertiesUtil.getValue("REDIS_HOST");//115.29.245.240

	//Redis的端口号
	private static int PORT = Integer.parseInt(PropertiesUtil.getValue("REDIS_PORT","7900"));

	//访问密码
	private static String AUTH = PropertiesUtil.getValue("REDIS_PWD");

	//可用连接实例的最大数目，默认值为8；
	//如果赋值为-1，则表示不限制；如果pool已经分配了maxActive个jedis实例，则此时pool的状态为exhausted(耗尽)。
	private static int MAX_ACTIVE = Integer.parseInt(PropertiesUtil.getValue("REDIS_MAX_ACTIVE"));

	//控制一个pool最多有多少个状态为idle(空闲的)的jedis实例，默认值也是8。
	private static int MAX_IDLE = Integer.parseInt(PropertiesUtil.getValue("REDIS_MAX_IDLE"));

	//等待可用连接的最大时间，单位毫秒，默认值为-1，表示永不超时。如果超过等待时间，则直接抛出JedisConnectionException；
	private static int MAX_WAIT = Integer.parseInt(PropertiesUtil.getValue("REDIS_MAX_WAIT"));

	private static int TIMEOUT = Integer.parseInt(PropertiesUtil.getValue("REDIS_TIMEOUT"));

	//在borrow一个jedis实例时，是否提前进行validate操作；如果为true，则得到的jedis实例均是可用的；
	private static boolean TEST_ON_BORROW = true;

	private static JedisPool jedisPool = null;

	/**
	 * 初始化Redis连接池
	 */
	static {
		try {
			JedisPoolConfig config = new JedisPoolConfig();
			config.setMaxTotal(MAX_ACTIVE);
			//config.setMaxActive(MAX_ACTIVE);
			config.setMaxIdle(MAX_IDLE);
			//config.setMaxWait(MAX_WAIT);
			config.setMaxWaitMillis(MAX_WAIT);
			config.setTestOnBorrow(TEST_ON_BORROW);
			jedisPool = new JedisPool(config, ADDR, PORT, TIMEOUT, AUTH);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 获取Jedis实例
	 * @return
	 */
	public synchronized static Jedis getJedis() {
		try {
			if (jedisPool != null) {
				Jedis resource = jedisPool.getResource();
				return resource;
			} else {
				return null;
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * 释放jedis资源
	 * @param jedis
	 */
	public static void returnResource(final Jedis jedis) {
		if (jedis != null) {
			jedisPool.returnResource(jedis);
		}
	}

	/**
	 * 根据key设置字符串值
	 * @param key
	 * @param value
	 * @return
	 * @throws Exception
	 */
	public static void setString(String key, String value) throws Exception {

		Jedis jedis = getJedis();

		if (jedis == null) {
			throw new Exception("getJedis error!");
		}

		//result = jedis.sadd(key, value);
		jedis.set(key, value);

		if (jedis != null) {
			try {
				returnResource(jedis);
			} catch (Exception e) {
				logger.error("returnResource error!");
				e.printStackTrace();
			}
		}

	}

	/**
	 * 根据key获取字符串值
	 * @param key
	 * @param value
	 * @return
	 * @throws Exception
	 */
	public static String getString(String key) throws Exception {
		String result = "";

		Jedis jedis = getJedis();

		if (jedis == null) {
			throw new Exception("getJedis error!");
		}

		result = jedis.get(key);

		if (jedis != null) {
			try {
				returnResource(jedis);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("returnResource error!");
			}
		}

		return result;
	}
	
	public static List<String> getStrings(List<String> keys) throws Exception {
		List<String> result = new ArrayList<String>();

		Jedis jedis = getJedis();

		if (jedis == null) {
			throw new Exception("getJedis error!");
		}
		for(String key : keys){
			result.add(jedis.get(key));
		}
		if (jedis != null) {
			try {
				returnResource(jedis);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("returnResource error!");
			}
		}
		return result;
	}

	/**
	 * 模糊匹配redis中key的集合
	 * 
	 * @param pattern
	 * @return 返回匹配到的所有key的集合
	 * @throws Exception
	 */
	public static Set<String> getKeys(String pattern) throws Exception {
		Set<String> keys = new HashSet<String>();
		
		Jedis jedis = getJedis();
		if (jedis == null) {
			throw new Exception("getJedis error!");
		}
		
		keys = jedis.keys(pattern);
		
		if (jedis != null) {
			try {
				returnResource(jedis);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("returnResource error!");
			}
		}
		return keys;
	}

	/**
	 * 批量存入redis
	 * @param keys
	 * @param values
	 * @throws Exception
	 */
	public static void setBytes(List<byte[]> keys, List<byte[]> values)
			throws Exception {
		Jedis jedis = getJedis();

		if (jedis == null) {
			logger.error("getJedis error!");
		}

		byte[] key = new byte[30];
		byte[] value = new byte[30];
		//遍历参数list
		for (int i = 0; i < keys.size(); i++) {
			//获取每一个key value
			key = keys.get(i);
			value = values.get(i);
			jedis.set(key, value);
		}

		if (jedis != null) {
			try {
				returnResource(jedis);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("returnResource error!");
			}
		}

	}
	
	/**
	 * 批量存入redis
	 * @param keys
	 * @param values
	 * @throws Exception
	 */
	public static void setStrings(List<String> keys, List<String> values)
			throws Exception {
		Jedis jedis = getJedis();

		if (jedis == null) {
			logger.error("getJedis error!");
		}

		String key = "";
		String value = "";
		logger.debug("本次更新数据："+keys.size());
		Pipeline p = jedis.pipelined();
		//遍历参数list
		for (int i = 0; i < keys.size(); i++) {
			key = keys.get(i);
			value = values.get(i);
			p.set(key, value);
		}
		p.sync();
		if (jedis != null) {
			try {
				returnResource(jedis);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("returnResource error!");
			}
		}

	}

	/**
	 * 根据key值获取byte[]
	 * @param key
	 * @return
	 * @throws RedisError
	 */
	public static byte[] getBytes(String key) throws Exception {
		byte[] bytesVal = null;
		Jedis jedis = getJedis();

		if (jedis == null) {
			logger.error("getJedis error!");
		} else if (key == null || key.trim().equals("")) {
			logger.error("key error!");
		}

		bytesVal = jedis.get(key.getBytes());

		if (jedis != null) {
			try {
				returnResource(jedis);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("returnResource error!");
			}
		}

		return bytesVal;
	}

	
	/**
	 * 存入redis
	 * @param keys
	 * @param values
	 * @throws Exception
	 */
	public static void setHSet(String key, String field, String value)
			throws Exception {
		Jedis jedis = getJedis();

		if (jedis == null) {
			logger.error("getJedis error!");
		}
		jedis.hset(key, field, value);
		if (jedis != null) {
			try {
				returnResource(jedis);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("returnResource error!");
			}
		}
	}
	
	/**
	 * 存入redis
	 * @param keys
	 * @param values
	 * @throws Exception
	 */
	public static void setHSet(String key, List<String> fields, List<String> values)
			throws Exception {
		Jedis jedis = getJedis();
		if (jedis == null) {
			logger.error("getJedis error!");
		}
		String field = "", value = "";
		// 遍历参数list,使用pipeline hmset
		Pipeline p = jedis.pipelined();
		Map<String, String> data = new HashMap<String, String>();
		for (int i = 0; i < 10000; i++) {
			data.clear();
			//获取每一个key value
			field = fields.get(i);
			value = values.get(i);
			data.put(field, value);
			p.hmset(key, data);
		}
		p.sync();
		if (jedis != null) {
			try {
				returnResource(jedis);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("returnResource error!");
			}
		}
	}
	
	public static String hgetValue(String key, String field)
			throws Exception {
		Jedis jedis = getJedis();

		if (jedis == null) {
			logger.error("getJedis error!");
		}
		String value = jedis.hget(key, field);
		if (jedis != null) {
			try {
				returnResource(jedis);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("returnResource error!");
			}
		}
		return value;
	}
	
	public static List<String> hgetKey(String key, String... fields)
			throws Exception {
		Jedis jedis = getJedis();

		if (jedis == null) {
			logger.error("getJedis error!");
		}
		List<String> list = jedis.hmget(key, fields);
		if (jedis != null) {
			try {
				returnResource(jedis);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("returnResource error!");
			}
		}
		return list;
	}
	
	/**
	 * 获取redis hgetKeys
	 * @param keys
	 * @param values
	 * @throws Exception
	 */
	public static Map<String, String> hgetKeys(String key)
			throws Exception {
		Jedis jedis = getJedis();

		if (jedis == null) {
			logger.error("getJedis error!");
		}
		Map<String, String> map = jedis.hgetAll(key);
		if (jedis != null) {
			try {
				returnResource(jedis);
			} catch (Exception e) {
				e.printStackTrace();
				logger.error("returnResource error!");
			}
		}
		return map;
	}
	
	public static void main(String[] args) {
		try {
//			setString("g.1000000045.21.1.trans","11QQ");
//			setString("g.1000000045.21.2.trans","22QQ");
//			setString("g.1000000045.54.3.trans","33QQ");
//			setString("g.1000000045.4.4.trans","44QQ");
			String key = "g.1000000045.21.*.trans";
			key = "bike-site-*";
			Set<String> keys = getKeys(key);
			System.out.println("size="+keys.size());  
			Iterator<String> it = keys.iterator();
//			java.util.Date start = new java.util.Date();
			List<String> keyss = new ArrayList<String>();
			while (it.hasNext()) {  
				String str = it.next(); 
				keyss.add(str);
//				String value = getString(str);
//				BikeBean bb = new BikeBean();
//				bb = JSON.parseObject(value, BikeBean.class);
//				bikes.add(bb);
////				System.out.println("key="+str+"&&&value="+value);  
			}
			System.out.println(keyss.size());
//			java.util.Date end = new java.util.Date();
//			System.out.println(end.getTime()-start.getTime());
//			System.out.println(bikes.size());
			
			
			
			List<BikeBean> bikes = new ArrayList<BikeBean>();
			List<String> values = getStrings(keyss);
			System.out.println(values.size());
//			for(String value : values){
//				BikeBean bb = new BikeBean();
//				bb = JSON.parseObject(value, BikeBean.class);
//				bikes.add(bb);
//			}
			System.out.println(bikes.size());
//			setHSet("bike-position", "我靠", "我存入成功啦,oH yeah");
			
//			Jets jedis = getJedis();
//			String str = jedis.hget("bike-normal-position", "*|*");
//			System.out.println(str);
//			Map<String , String > map = jedis.hgetAll("bike-normal-position");
//			Iterator<Entry<String, String>> it = map.entrySet().iterator();
//			while (it.hasNext()) {  
//				Entry<String, String> str = it.next(); 
//				System.out.println(str);
//			}
			
			
			
			
			
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}